perm filename IMAGE.SAI[SYS,HE] blob
sn#056326 filedate 1973-08-02 generic text, type T, neo UTF8
00100
00200
00300
00400
00500
00600 PROCEDURE DIS_VERT(SHORT INTEGER J);
00700
00800 ⊃ Here we display the lines forming a vertex with arrows
00900 pointing toward the vertex;
01000
01100 BEGIN
01200 SHORT INTEGER I,K;
01300 SHORT REAL XC,YC,DX,DY,XV,YV,DELX,DELY,SIGX,SIGY;
01400 XV←VERTEX[J,1];
01500 YV←VERTEX[J,2];
01600 DPYSET(BUF);
01700 BOUNDARY(X1,Y2,X2,Y1);
01800 FOR I←1 STEP 1 UNTIL VERTEX[J,3] DO
01900 BEGIN
02000 K←VERTEX[J,3+I];
02100 LINE_DISP(K);
02200 XC←(HUMPS[K,FPOINT+1]+HUMPS[K,HUMPS[K,6]+1])/2.;
02300 YC←(HUMPS[K,FPOINT+2]+HUMPS[K,HUMPS[K,6]+2])/2.;
02400 DELX←XV-XC;
02500 DELY←YV-YC;
02600 SIGX←SIGN(DELX);
02700 SIGY←SIGN(DELY);
02800 DX←SIGX*ABS(HUMPS[K,SINTHETA]);
02900 DY←SIGY*ABS(HUMPS[K,COSTHETA]);
03000 IF ABS(DX)>0.5 THEN ARROW(XC,YC-2,DX,DY)
03100 ELSE ARROW(XC-3,YC,DX,DY);
03200 AIVECT(-400, 460-60*I);
03300 DPYSST(" DX="&CVG(DX)&" DY="&CVG(DY));
03400 AIVECT(-400,430-60*I);
03500 DPYSST(" XV - XC="&CVG(DELX)&" YV - YC ="&CVG(DELY));
03600 END;
03700 DPYOUT(1);
03800 END;
03900
00100 PROCEDURE FINDIMAG(INTEGER MODLINES,DIREC,SEARCH;
00200 REAL TOLER;REAL ARRAY CORNMOD);
00300
00400 ⊃ Here we try to find a line or corner in the window selected
00500 by SRCHIMAG;
00600
00700 BEGIN "FINDIMAG"
00800 SHORT INTEGER N2FOUND,N3FOUND;
00900 SHORT REAL XX,YY,X,Y;
01000
01100
01200 DEFINE TRY(J) = { IF COMPARE(J) THEN
01300 BEGIN
01400 STORE_CORN(J,MODLINES);
01500 IF ¬WANT_ALL THEN GO TO SUCCESS;
01600 END; };
01700
01800 BOOLEAN PROCEDURE FIT(INTEGER N,J);
01900 ⊃ Here we compare the edge line "N" with the model line "J";
02000 BEGIN "FIT"
02100 SHORT REAL TEMP;
02200 IF DEB_EYE THEN OUTSTR(" IN FIT --- N="&CVS(N)&" J="&CVS(J)ACRLF);
02300 IF HUMPS[N,DIRCOS]*CORNMOD[J,COSDIR]
02400 +HUMPS[N,DIRSIN]*CORNMOD[J,SINDIR]<1-TOLER THEN
02500 BEGIN IF DEB_EYE THEN OUTSTR(" REJECTED BECAUSE OF ANGULAR TOLERANCE
02600 DXL="&CVG(HUMPS[N,DIRSIN])&" DXM="&CVG(CORNMOD[J,SINDIR])&"
02700 DYL="&CVG(HUMPS[N,DIRCOS])&" DYM="&CVG(CORNMOD[J,COSDIR])ACRLF);
02800 RETURN(0); END;
02900 IF DIREC=0∨(J=2∧MODLINES=3) THEN RETURN(-1);
03000 TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
03100 IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
03200 RETURN(-1) ELSE
03300 BEGIN
03400 IF DEB_EYE THEN OUTSTR("REJECTED BECAUSE
03500 WRONG INTENSITY DIRECTION --TEMP="&CVG(TEMP)ACRLF);
03600 RETURN(0);
03700 END;
03800 END "FIT";
03900
04000
04100 BOOLEAN PROCEDURE ABSFIT(INTEGER N,J);
04200 ⊃ This is like FIT except we accept either direction for the line;
04300 BEGIN "ABSFIT"
04400 SHORT REAL TEMP;
04500 IF ABS(HUMPS[N,COSTHETA]*CORNMOD[J,COSTHETA]
04600 +HUMPS[N,SINTHETA]*CORNMOD[J,SINTHETA])<1-TOLER THEN
04700 RETURN(0);
04800 IF DIREC=0∨(J=2∧MODLINES=3) THEN RETURN(-1);
04900 TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
05000 IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
05100 RETURN(-1) ELSE RETURN(0);
05200 END "ABSFIT";
00100
00200
00300 INTEGER PROCEDURE BESTFIT(INTEGER N);
00400 ⊃ Here we compare the edge line "N" with the all the model lines;
00500 BEGIN "BFIT"
00600 SHORT REAL TEMP,MAX,MAXNJ;
00700 SHORT INTEGER J,ISAVE;
00800 LABEL LAST,SAVE;
00900 MAX←0; ISAVE←0;
01000 FOR J←1 STEP 1 UNTIL MODLINES DO
01100 BEGIN
01200 IF DEB_EYE THEN OUTSTR(" IN BESTFIT --- N="&CVS(N)&" MODL="&CVS(J)ACRLF);
01300 IF (MAXNJ←HUMPS[N,DIRCOS]*CORNMOD[J,COSDIR]
01400 +HUMPS[N,DIRSIN]*CORNMOD[J,SINDIR])<1-TOLER THEN
01500 BEGIN
01600 IF DEB_EYE THEN OUTSTR(" REJECTED BECAUSE OF ANGULAR TOLERANCE
01700 DXL="&CVG(HUMPS[N,DIRSIN])&" DXM="&CVG(CORNMOD[J,SINDIR])&"
01800 DYL="&CVG(HUMPS[N,DIRCOS])&" DYM="&CVG(CORNMOD[J,COSDIR])ACRLF);
01900 GO TO LAST;
02000 END;
02100 IF DIREC=0∨(J=2∧MODLINES=3) THEN GO TO SAVE;
02200 TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
02300 IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
02400 GO TO SAVE ELSE
02500 BEGIN
02600 IF DEB_EYE THEN OUTSTR("REJECTED BECAUSE
02700 WRONG INTENSITY DIRECTION --TEMP="&CVG(TEMP)ACRLF);
02800 GO TO LAST;
02900 END;
03000 SAVE: IF MAXNJ> MAX THEN
03100 BEGIN
03200 MAX←MAXNJ;
03300 ISAVE←J;
03400 END;
03500 LAST: END;
03600 RETURN(ISAVE);
03700
03800 END "BFIT";
03900
04000
00100
00200
00300
00400 INTEGER PROCEDURE ROUGH_COMPARE;
00500 ⊃ Here we throw out lines which do not fit any model line.
00600 No comparison of the direction of the line with respect
00700 to vertex is made;
00800
00900 BEGIN "COMP"
01000 SHORT INTEGER N,I,J,JHUMP,NFOUND;
01100 SHORT REAL TEMP;
01200 SHORT INTEGER ARRAY REJ[1:3];
01300 LABEL AFTER, NOFIT, REJECT,FOUND;
01400 NFOUND←0;
01500 FOR N←0 STEP 1 UNTIL NLINES-1 DO
01600 BEGIN "OUTER"
01700 FOR J←1 STEP 1 UNTIL MODLINES DO
01800 BEGIN
01900 IF ABS(HUMPS[N,COSTHETA]*CORNMOD[J,COSTHETA]
02000 +HUMPS[N,SINTHETA]*CORNMOD[J,SINTHETA])<1-TOLER THEN
02100 BEGIN REJ[J]←1; GO TO NOFIT; END;
02200 IF DIREC=0∨(J=2∧MODLINES=3) THEN GO TO FOUND;
02300 TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
02400 IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
02500 FOUND: BEGIN NFOUND←NFOUND+1; GO TO AFTER; END;
02600 REJ[J]←-1;
02700 NOFIT: END;
02800 REJECT: IF DEB_EYE THEN
02900 BEGIN
03000 DPYSET(BUF);
03100 BOUNDARY(X1,Y2,X2,Y1);
03200 LINE_DISP(N);
03300 AIVECT(-400,420);
03400 DPYSST(" THIS LINE REJECTED BECAUSE (");
03500 FOR I←1 STEP 1 UNTIL MODLINES DO
03600 BEGIN
03700 IF REJ[I]>0 THEN
03800 DPYSST(CVS(I)&") WRONG ANGLE ")
03900 ELSE DPYSST(CVS(I)&") WRONG INTENSITY DIRECTION");
04000 AIVECT(-300,420-30*I);
04100 END;
04200 DPYSST(" THETA="& CVG(HUMPS[N,1])
04300 &" COSTH="& CVG(HUMPS[N,COSTHETA])
04400 &"SINTH="&CVG(HUMPS[N,SINTHETA]));
04500 DPYOUT(1);
04600 END;
04700 JHUMP←HUMPS[NLINES-1,6]+2;
04800 FOR I←1 STEP 1 UNTIL JHUMP DO
04900 HUMPS[N,I]←HUMPS[NLINES-1,I];
05000 NLINES←NLINES-1;
05100 N←N-1;
05200 AFTER: END "OUTER";
05300 IF DEB_EYE THEN
05400 FOR N←0 STEP 1 UNTIL NLINES-1 DO
05500 OUTSTR(" THETA="& CVG(HUMPS[N,1])
05600 &" COSTH="& CVG(HUMPS[N,COSTHETA])
05700 &"SINTH="&CVG(HUMPS[N,SINTHETA])ACRLF);
05800 RETURN(NFOUND); ⊃ Return the number of lines that were found;
05900 END "COMP";
06000
00100
00200
00300 BOOLEAN PROCEDURE DIR_TEST(SHORT INTEGER NVERT);
00400
00500 ⊃ Here we test each line forming vertex NVERT to see if they
00600 match any model line considering direction with
00700 respect to the vertex;
00800
00900 BEGIN "DIR"
01000 SHORT INTEGER N,J,I,K,NFOUND;
01100 SHORT REAL TEMP,XB,YB,XF,YF;
01200 SHORT REAL XC,YC,DXL,DYL,DXM,DYM,XV,YV,DELX,DELY,SIGX,SIGY;
01300 BOOLEAN TEST;
01400 SHORT INTEGER ARRAY REJ[1:3];
01500 LABEL AFTER,AFT1, NOFIT, REJECT;
01600 NFOUND←0; TEST←0;
01700 XV←VERTEX[NVERT,1];
01800 YV←VERTEX[NVERT,2];
01900 FOR I←1 STEP 1 UNTIL VERTEX[NVERT,3] DO
02000 BEGIN "OUTER"
02100 N←VERTEX[NVERT,3+I];
02200 IF HUMPS[N,3]≠NVERT∧HUMPS[N,4]≠NVERT∧NVERT≤NVERTEX THEN
02300 BEGIN
02400 IF DIS_EYE THEN OUTSTR(" LINE "&CVS(N)&
02500 " IS INTERSECTED IN MIDDLE"ACRLF);
02600 GO TO AFTER;
02700 END;
02800 XB←HUMPS[N,FPOINT+1]; XF←HUMPS[N,HUMPS[N,6]+1];
02900 YB←HUMPS[N,FPOINT+2]; YF←HUMPS[N,HUMPS[N,6]+2];
03000 XC←(XB+XF)/2.; YC←(YB+YF)/2.;
03100 IF (XV-XB)↑2+(YV-YB)↑2>(XV-XF)↑2+(YV-YF)↑2 THEN
03200 ⊃ Filling array HUMPS with "VERT_END";
03300 HUMPS[N,VERT_END]←HUMPS[N,6]
03400 ELSE HUMPS[N,VERT_END]←FPOINT;
03500 DELX←XV-XC;
03600 DELY←YV-YC;
03700 SIGX←SIGN(DELX);
03800 SIGY←SIGN(DELY);
03900 ⊃ FILLING ARRAY HUMPS WITH "DIRSIN" AND "DIRCOS" WHICH ARE USED
04000 LATER IN "COMPARE" ("FIT" THAT IS);
04100 DXL←HUMPS[N,DIRSIN]←SIGX*ABS(HUMPS[N,SINTHETA]);
04200 DYL←HUMPS[N,DIRCOS]←SIGY*ABS(HUMPS[N,COSTHETA]);
04300 FOR J←1 STEP 1 UNTIL MODLINES DO
04400 BEGIN
04500 DXM←CORNMOD[J,SINDIR];
04600 DYM←CORNMOD[J,COSDIR];
04700 IF DEB_EYE THEN OUTSTR(" LINE "&CVS(N)&" DXL="&CVG(DXL)&" DYL="&CVG(DYL)&"
04800 MODEL LINE "&CVS(J)&" DXM="&CVG(DXM)&" DYM="&CVG(DYM)ACRLF);
04900
05000 IF DXL*DXM+DYL*DYM<1-TOLER THEN
05100 BEGIN REJ[J]←1; GO TO NOFIT; END;
05200 IF DIREC=0∨(J=2∧MODLINES=3) THEN GO TO AFTER;
05300 TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
05400 IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
05500 GO TO AFTER;
05600 REJ[J]←-1;
05700 NOFIT: END;
05800 REJECT: NFOUND←-1;
05900 IF DEB_EYE THEN ⊃ Tell why each line is rejected and
06000 show line on screen;
06100 BEGIN
06200 DPYSET(BUF);
06300 BOUNDARY(X1,Y2,X2,Y1);
06400 LINE_DISP(N);
06500 AIVECT(-400,420);
06600 DPYSST(" THIS LINE REJECTED BECAUSE (");
06700 FOR K←1 STEP 1 UNTIL MODLINES DO
06800 BEGIN
06900 IF REJ[K]>0 THEN
07000 DPYSST(CVS(K)&") WRONG ANGULAR DIRECTION
07100 WITH RESPECT TO VERTEX ")
07200 ELSE DPYSST(CVS(K)&") WRONG INTENSITY DIRECTION");
07300 AIVECT(-300,420-30*K);
07400 END;
07500 DPYSST(" THETA="& CVG(HUMPS[N,1])
07600 &" COSTH="& CVG(HUMPS[N,COSTHETA])
07700 &"SINTH="&CVG(HUMPS[N,SINTHETA]));
07800 DPYOUT(1);
07900 END;
08000 IF NVERT>NVERTEX THEN GO TO AFTER;
08100 ⊃ THIS IS USED FOR THE CASE OF TEST-VERTICIES;
08200 VERTEX[NVERT,3+I]←VERTEX[NVERT,VERTEX[NVERT,3]+3];
08300 K←VERTEX[NVERT,3]←VERTEX[NVERT,3]-1;
08400 AFT1: IF HUMPS[N,3]=NVERT THEN
08500 HUMPS[N,3]←HUMPS[N,13]←HUMPS[N,14]←-1
08600 ELSE IF HUMPS[N,4]=NVERT THEN
08700 HUMPS[N,4]←HUMPS[N,15]←HUMPS[N,16]←-1;
08800 IF TEST THEN GO TO AFTER;
08900 IF K<2 THEN
09000 BEGIN
09100 IF NVERT=NVERTEX THEN NVERTEX←NVERTEX-1 ELSE
09200 BEGIN
09300 VERTEX[NVERT,1]←-1000.;
09400 VERTEX[NVERT,2]←-1000.;
09500 VERTEX[NVERT,3]←0;
09600 END;
09700 IF K=0 THEN GO TO AFTER;
09800 N←VERTEX[NVERT,4];
09900 TEST←-1;
10000 GO TO AFT1;
10100 END;
10200 IF I≤VERTEX[NVERT,3] THEN I←I-1;
10300 AFTER: END "OUTER";
10400 RETURN(NFOUND); ⊃ Return TRUE if you find a line to reject;
10500 END "DIR";
10600
00100
00200 BOOLEAN PROCEDURE COMPARE(SHORT INTEGER NVERT);
00300 ⊃ Here we compare all the model lines with all the lines
00400 forming vertex NVERT. Now the model lines must be
00500 fitted be different lines;
00600
00700 BEGIN "PARE"
00800 SHORT INTEGER LINE1,LINE2,LINE3,I,K;
00900 LABEL FAIL;
01000 IF DEB_EYE THEN OUTSTR(" IN COMPARE -- VERTEX NUMBER = "&CVS(NVERT)&"
01100 NUMBER OF LINES = "&CVS(VERTEX[NVERT,3])ACRLF);
01200 LINE1←VERTEX[NVERT,4];
01300 LINE2←VERTEX[NVERT,5];
01400 IF MODLINES=2 THEN
01500 BEGIN
01600 IF (FIT(LINE1,1)∧FIT(LINE2,2))
01700 ∨(FIT(LINE2,1)∧FIT(LINE1,2)) THEN
01800 RETURN(-1);
01900 GO TO FAIL;
02000 END;
02100 IF MODLINES=3 THEN
02200 BEGIN
02300 LINE3←VERTEX[NVERT,6];
02400 IF (FIT(LINE1,1)∧FIT(LINE2,2)∧FIT(LINE3,3))
02500 ∨(FIT(LINE1,1)∧FIT(LINE3,2)∧FIT(LINE2,3))
02600 ∨(FIT(LINE2,1)∧FIT(LINE1,2)∧FIT(LINE3,3))
02700 ∨(FIT(LINE2,1)∧FIT(LINE3,2)∧FIT(LINE1,3))
02800 ∨(FIT(LINE3,1)∧FIT(LINE1,2)∧FIT(LINE2,3))
02900 ∨(FIT(LINE3,1)∧FIT(LINE2,2)∧FIT(LINE1,3)) THEN
03000 RETURN(-1);
03100 GO TO FAIL;
03200 END;
03300 FAIL: IF NVERT>NVERTEX THEN RETURN(0);
03400 ⊃ THIS IS USED FOR THE CASE OF TEST-VERTICIES;
03500 ⊃ Now we destroy this vertex;
03600 FOR I←1 STEP 1 UNTIL MODLINES DO
03700 BEGIN
03800 K←VERTEX[NVERT,3+I];
03900 IF HUMPS[K,3]=NVERT THEN
04000 HUMPS[K,3]←HUMPS[K,13]←HUMPS[K,14]←-1
04100 ELSE IF HUMPS[K,4]=NVERT THEN
04200 HUMPS[K,4]←HUMPS[K,15]←HUMPS[K,16]←-1;
04300 END;
04400 IF NVERT=NVERTEX THEN NVERTEX←NVERTEX-1 ELSE
04500 BEGIN
04600 VERTEX[NVERT,1]←-1000.;
04700 VERTEX[NVERT,2]←-1000.;
04800 VERTEX[NVERT,3]←0;
04900 END;
05000 RETURN(0);
05100 END "PARE";
05200
00100
00200 SIMPLE PROCEDURE STORE_LINE(SHORT INTEGER N);
00300 ⊃ Here we store the line data in array DIR_EYE;
00400 BEGIN "LSTOR"
00500 SHORT REAL XB,YB,XF,YF;
00600 SHORT INTEGER SIGX,SIGY;
00700 XB←HUMPS[N,FPOINT+1]; XF←HUMPS[N,HUMPS[N,6]+1];
00800 YB←HUMPS[N,FPOINT+2];YF←HUMPS[N,HUMPS[N,6]+2];
00900 SIGX←SIGN(XF-XB);
01000 SIGY←SIGN(YF-YB);
01100 DIR_EYE[0,1]←NCORNERS+1;
01200 DIR_EYE[NCORNERS,2]←(XB+XF)/2.;
01300 DIR_EYE[NCORNERS,3]←(YB+YF)/2.;
01400 DIR_EYE[NCORNERS,5]←HUMPS[N,THET];
01500 DIR_EYE[NCORNERS,6]←HUMPS[N,CEE];
01600 DIR_EYE[NCORNERS,7]←SIGX*ABS(HUMPS[N,SINTHETA]);
01700 DIR_EYE[NCORNERS,8]←SIGY*ABS(HUMPS[N,COSTHETA]);
01800 NCORNERS←NCORNERS+1;
01900 END "LSTOR";
02000
02100
02200 SIMPLE PROCEDURE STORE_CORN(SHORT INTEGER I,MODLINES);
02300 ⊃ Here we store the corner data in array DIR_EYE;
02400 BEGIN "STOR"
02500 SHORT INTEGER K,J,KI,JI,NCT2,ZOR4;
02600 LABEL LAST1,LAST2;
02700 IF NCORNERS≥1 THEN
02800 FOR J←0 STEP 1 UNTIL NCORNERS-1 DO
02900 BEGIN
03000 NCT2←2*J;
03100 IF ABS(VERTEX[I,1]-DIR_EYE[NCT2,2])<DINT
03200 ∧ABS(VERTEX[I,2]-DIR_EYE[NCT2,3])<DINT THEN
03300 BEGIN "LINEMATCH"
03400 FOR KI←1 STEP 1 UNTIL MODLINES DO
03500 BEGIN
03600 IF KI=2 THEN
03700 BEGIN
03800 ZOR4←0;
03900 NCT2←NCT2+1;
04000 END
04100 ELSE ZOR4←4;
04200 FOR K←1 STEP 1 UNTIL MODLINES DO
04300 BEGIN
04400 JI←VERTEX[I,3+K];
04500 IF ABS(HUMPS[JI,THET]-DIR_EYE[NCT2,ZOR4+1])<NDTH/2.
04600 ∧ABS(HUMPS[JI,CEE]-DIR_EYE[NCT2,ZOR4+2])<NDC/2. THEN GO TO LAST1;
04700 END;
04800 GO TO LAST2;
04900 LAST1: END;
05000 RETURN;
05100 END "LINEMATCH";
05200 LAST2: END;
05300 NCT2←2*NCORNERS;
05400 NCORNERS←NCORNERS+1;
05500 IF EXT_LINE THEN DIR_EYE[0,1]←-1
05600 ELSE DIR_EYE[0,1]←NCORNERS;
05700 DIR_EYE[NCT2,2]←VERTEX[I,1];
05800 DIR_EYE[NCT2,3]←VERTEX[I,2];
05900 IF MODLINES=3 THEN DIR_EYE[NCT2,4]←VERTEX[I,VERTGAP];
06000 FOR K←1 STEP 1 UNTIL MODLINES DO
06100 BEGIN
06200 IF K=2 THEN
06300 BEGIN
06400 ZOR4←0;
06500 NCT2←NCT2+1;
06600 END
06700 ELSE ZOR4←4;
06800 J←VERTEX[I,3+K];
06900 DIR_EYE[NCT2,ZOR4+1]←HUMPS[J,THET];
07000 DIR_EYE[NCT2,ZOR4+2]←HUMPS[J,CEE];
07100 DIR_EYE[NCT2,ZOR4+3]←HUMPS[J,DIRSIN];
07200 DIR_EYE[NCT2,ZOR4+4]←HUMPS[J,DIRCOS];
07300 END;
07400 IF NCORNERS≥5 THEN WANT_ALL←0;
07500
07600 END "STOR";
07700
00100
00200
00300 PROCEDURE SET_FOR_SCAN(SHORT REAL XC,YC,DX,DY);
00400 ⊃ Here we call for an edge_scan and line_find in a rectangular
00500 region. One end is centered about (XC,YC) and the
00600 rectangle points in the direction cos(α)=-DX, sin(α)=-DY;
00700
00800 BEGIN "SETF"
00900 SHORT INTEGER YFIN, XCSAVE,YCSAVE;
01000 SHORT REAL X1,X2,X3,X4,Y1,Y2,Y3,Y4,XS1,XS2,YS1,YS2;
01100 SHORT REAL DTHSAVE,DCSAVE,DSSAVE,DGAPSAVE,ALPHA,DALPH;
01200 LABEL AFRECT,RESTORE;
01300
01400
01500
01600 ALPHA←ATAN(DY/DX)+PIO2;
01700 DALPH←ABS(ACOS(1.-TOLER));
01800 IF DEB_EYE THEN
01900 BEGIN
02000 OUTSTR(" IN SET_FOR_SCAN "&CRLF);
02100 PRINT(ALPHA);
02200 PRINT(DALPH);
02300 END;
02400 X1←XC-5.*DY;
02500 Y1←YC+5.*DX;
02600 X2←X1-15.*DX+10.*DY;
02700 Y2←Y1-15.*DY-10.*DX;
02800 X3←X1-15.*DX;
02900 Y3←Y1-15.*DY;
03000 Y4←Y1-10.*DX;
03100 X4←X1+10.*DY;
03200
03300 ⊃ X1,Y1, X2,Y2, X3,Y3, X4,Y4 define the rotated rectangle;
03400
03500 IF X1≤X2∧X1≤X3∧X1≤X4 THEN XS1←X1
03600 ELSE IF X2≤X3∧X2≤X4 THEN XS1←X2
03700 ELSE IF X3≤X4 THEN XS1←X3 ELSE XS1←X4;
03800 IF X1≥X2∧X1≥X3∧X1≥X4 THEN XS2←X1
03900 ELSE IF X2≥X3∧X2≥X4 THEN XS2←X2
04000 ELSE IF X3≥X4 THEN XS2←X3 ELSE XS2←X4;
04100 IF Y1≥Y2∧Y1≥Y3∧Y1≥Y4 THEN YS2←Y1
04200 ELSE IF Y2≥Y3∧Y2≥Y4 THEN YS2←Y2
04300 ELSE IF Y3≥Y4 THEN YS2←Y3 ELSE YS2←Y4;
04400 IF Y1≤Y2∧Y1≤Y3∧Y1≤Y4 THEN YS1←Y1
04500 ELSE IF Y2≤Y3∧Y2≤Y4 THEN YS1←Y2
04600 ELSE IF Y3≤Y4 THEN YS1←Y3 ELSE YS1←Y4;
04700
04800 ⊃ OUTSTR(" X1="&CVG(X1)&
04900 " Y1="&CVG(Y1)&
05000 " Y2="&CVG(Y2)&
05100 " X2="&CVG(X2)&
05200 " X3="&CVG(X3)&
05300 " Y3="&CVG(Y3)&
05400 " Y4="&CVG(Y4)&
05500 " X4="&CVG(X4)&CRLF);
05600
05700 ⊃ XS1,YS1, XS2,YS2, define the large rectangle which encloses
05800 the rotated rectangle;
05900 IF ¬DIS_EYE THEN GO TO AFRECT;
06000 AIVECT(TX(X1),TY(Y1));
06100 AVECT(TX(X3),TY(Y3));
06200 AVECT(TX(X2),TY(Y2));
06300 AVECT(TX(X4),TY(Y4));
06400 AVECT(TX(X1),TY(Y1));
06500 DPYOUT(1);
06600 IF CAL_COMP THEN CALCOMP("LOOKL",BUF);
06700
06800 AFRECT: XCSAVE←LOOK_AT[2];
06900 YCSAVE←LOOK_AT[3];
07000
07100 LOOK_AT[2]←(XS1+XS2)/2;
07200 LOOK_AT[3]←(YS1+YS2)/2;
07300 LOOK_AT[5]←(YS2-YS1);
07400 LOOK_AT[4]←(XS2-XS1);
07500 DXY←(XS2+YS2)/SQ2;
07600 EXFLAG←0;
07700 GETPICTURE;
07800 IF DEB_EYE THEN
07900 BEGIN DISPLAY; PRINT(LOOK_AT[6]); PRINT(LOOK_AT[7]); END;
08000 IF EXFLAG=10 THEN GO TO RESTORE;
08100 EJINIT; ⊃ This initializes edge operator;
08200 YFIN←EDGE_SCAN(XC,YC,DX,DY); ⊃ Here we call the edge operator;
08300 DTHSAVE←NDTH;
08400 DCSAVE←NDC;
08500 DSSAVE←NDS;
08600 DGAPSAVE←NDGAP;
08700 NDTH←2*NDTH; ⊃ This makes it a little easier
08800 to find lines;
08900 NDC←2*NDC;
09000 NDS←10.;
09100 NDGAP←1.0;
09200
09300 IF CAL_COMP THEN CAL2_COMP←-1;
09400 GET_SOME_LINES(ALPHA,DALPH); ⊃ Here we call a line finder to
09500 to find lines with angle within DALPH of ALPHA;
09600
09700 ⊃ Now return all variables to their old values;
09800 CAL2_COMP←0;
09900 NDTH←DTHSAVE;
10000 NDC←DCSAVE;
10100 NDS←DSSAVE;
10200 NDGAP←DGAPSAVE;
10300 RESTORE: LOOK_AT[2]←XCSAVE;
10400 LOOK_AT[3]←YCSAVE;
10500 LOOK_AT[4]←X_WIDTH;
10600 LOOK_AT[5]←Y_WIDTH;
10700 END "SETF";
10800
00100
00200 BOOLEAN PROCEDURE TWO_LINE_VERT(SHORT INTEGER N,J,MODLINES);
00300
00400 ⊃ Here we see if lines N and J fit the model and form
00500 a satisfactory vertex;
00600
00700 BEGIN "TW"
00800 SHORT INTEGER K,L;
00900 REAL TEMP;
01000 LABEL AFT2;
01100
01200 K←NVERTEX+1;
01300 INTERSECT(N,J);
01400 VERTEX[K,1]←X;
01500 VERTEX[K,2]←Y;
01600 VERTEX[K,3]←2;
01700 VERTEX[K,4]←N;
01800 VERTEX[K,5]←J;
01900 IF DIR_TEST(K) THEN GO TO AFT2; ⊃ Forget it
02000 at least one line does not fit;
02100 IF MODLINES=2 THEN IF ¬COMPARE(K) THEN GO TO AFT2; ⊃ Forget it;
02200 IF DEB_EYE THEN DIS_VERT(K);
02300 N2FOUND←N2FOUND+1;
02400 XX←X;
02500 YY←Y;
02600 IF EXT_LINE THEN TEMP←16. ELSE TEMP←4.;
02700 FOR L←N,J DO
02800 ⊃ Testing for intersection inside of circle
02900 with slightly larger radius than usual;
03000 IF (X-HUMPS[L,HUMPS[L,VERT_END]+1])↑2
03100 +(Y-HUMPS[L,HUMPS[L,VERT_END]+2])↑2
03200 >TEMP*NDRADIUS*NDRADIUS THEN GO TO AFT2;
03300 NVERTEX←NVERTEX+1;
03400 FOR L←N,J DO
03500 ⊃ We are satisfied so we make this a real vertex;
03600 IF HUMPS[L,VERT_END]=FPOINT THEN
03700 BEGIN
03800 HUMPS[L,3]←K;
03900 HUMPS[L,13]←X;
04000 HUMPS[L,14]←Y;
04100 END ELSE
04200 BEGIN
04300 HUMPS[L,4]←K;
04400 HUMPS[L,15]←X;
04500 HUMPS[L,16]←Y;
04600 END;
04700 IF DIS_EYE THEN SHOW_LINES;
04800 IF MODLINES=3 THEN RETURN(-1);
04900 IF CAL_COMP THEN CALCOMP("VERTEX",BUF);
05000 STORE_CORN(K,MODLINES);
05100 RETURN(-1);
05200 AFT2: RETURN(0);
05300 END "TW";
05400
05500
05600 BOOLEAN PROCEDURE THREE_LINE_VERT(SHORT INTEGER N,J,L);
05700
05800 ⊃ Here we see if the three lines N,J, and L form a
05900 satisfactory vertex;
06000
06100 BEGIN "THREE"
06200 SHORT INTEGER K,NI;
06300 SHORT REAL VERT_GAP,TEMP;
06400 BOOLEAN TEST_GAP;
06500 LABEL AFT3;
06600
06700 TEST_GAP←0;
06800 K← NVERTEX+1;
06900 IF EXT_LINE THEN TEMP←3. ELSE TEMP←1.5;
07000 NDACC←TEMP*NDACC;
07100 IF ¬VERT_THREE(N,J,L,X,Y,VERT_GAP) THEN
07200 BEGIN
07300 ⊃ OUTSTR(CRLF&" VERTEX GAP = "&CVG(VERT_GAP));
07400 IF VERT_GAP<2.*NDACC THEN TEST_GAP←-1
07500 ELSE BEGIN NDACC←NDACC/TEMP; GO TO AFT3; END;
07600 END;
07700 ⊃ OUTSTR(CRLF&" VERTEX GAP = "&CVG(VERT_GAP));
07800 NDACC←NDACC/TEMP;
07900 VERTEX[K,1]←X;
08000 VERTEX[K,2]←Y;
08100 VERTEX[K,VERTGAP]←VERT_GAP;
08200 VERTEX[K,3]←MODLINES;
08300 VERTEX[K,4]←N;
08400 VERTEX[K,5]←J;
08500 VERTEX[K,6]←L;
08600 IF DIR_TEST(K) THEN GO TO AFT3; ⊃ At least one
08700 line does not fit;
08800 IF ¬COMPARE(K) THEN GO TO AFT3;
08900 IF DEB_EYE THEN DIS_VERT(K);
09000 N3FOUND←N3FOUND+1;
09100 XX←X;
09200 YY←Y;
09300 IF EXT_LINE THEN TEMP←16. ELSE TEMP←4.;
09400 FOR NI←N,J,L DO
09500 IF (X-HUMPS[NI,HUMPS[NI,VERT_END]+1])↑2
09600 +(Y-HUMPS[NI,HUMPS[NI,VERT_END]+2])↑2
09700 >TEMP*NDRADIUS*NDRADIUS THEN GO TO AFT3;
09800 IF TEST_GAP THEN GO TO AFT3;
09900 NVERTEX←NVERTEX+1; ⊃ Now we are satisfied
10000 so we make this a real vertex;
10100 FOR NI←N,J,L DO
10200 IF HUMPS[NI,VERT_END]=FPOINT THEN
10300 BEGIN
10400 HUMPS[NI,3]←K;
10500 HUMPS[NI,13]←X;
10600 HUMPS[NI,14]←Y;
10700 END ELSE
10800 BEGIN
10900 HUMPS[NI,4]←K;
11000 HUMPS[NI,15]←X;
11100 HUMPS[NI,16]←Y;
11200 END;
11300 IF DIS_EYE THEN SHOW_LINES;
11400 IF CAL_COMP THEN CALCOMP("VERTEX",BUF);
11500 STORE_CORN(K,MODLINES);
11600 RETURN(-1);
11700 AFT3: RETURN(0);
11800 END "THREE";
11900
12000
00100
00200
00300
00400 SHORT INTEGER DUM,F,J,K,L,N,TRN,SIGX,SIGY,LASTLINE,
00500 NUM_LINES,XFIN,YFIN,OTHER,OTHER2,WIDTH,HIGHT,NVERT,
00600 NI,I,ISAVE,SGN,FEATS,MATS,MAXDIM,MINDIM,L1,L2;
00700 SHORT REAL MAX,MIN,TEMP,XC,YC;
00800 SHORT REAL DX,DY,EDG_TIM,LIN_TIM;
00900 LABEL RECNTR,FLINES,NEXT2,NEXT3,NEXT4,NEX2,NEX3;
01000 LABEL NEX4,NEX5,NEX6,DNEXT1;
01100 LABEL NEED2_VERT,NEED3_VERT,TEST2_VERT,TEST3_VERT,FOL2,FOL3;
01200 LABEL SUCCESS, FAILURE,FAIL_COMP,TWO_LINES,ABOVE;
01300 LABEL TRY_AGAIN,LAST2,LAST3,LAST4,FEW_LINES,DNEXT;
01400
01500
01600
01700
01800 ⊃ Define the window;
01900
02000 IF LOOK_AT[4]>LOOK_AT[5]
02100 THEN BEGIN MINDIM←LOOK_AT[5]; MAXDIM←LOOK_AT[4]; END
02200 ELSE BEGIN MINDIM←LOOK_AT[4]; MAXDIM←LOOK_AT[5]; END;
02300 IF (LOOK_AT[4]*LOOK_AT[5])>50000 THEN
02400 BEGIN
02500 OUTSTR("FINDIMAG-FAILED: WINDOW TOO BIG FOR TVBUF (WIDTH="&
02600 CVS(LOOK_AT[4])&" HIGHT="&CVS(LOOK_AT[5])
02700 &")"ACRLF);
02800 EXFLAG←10; RETURN;
02900 END;
03000 IF MINDIM<5
03100 THEN BEGIN OUTSTR("FINDIMAG-FAILED: WINDOW TOO NARROW (MINDIM="&
03200 CVS(MINDIM)&")"ACRLF);
03300 EXFLAG←10; RETURN; END;
03400 WIDTH←LOOK_AT[4]; HIGHT←LOOK_AT[5];
03500
03600 ⊃ Accomodate, read in the window and display;
03700
03800 RECNTR:
03900 EXFLAG←0; EXT_LINE←0; DIR_EYE[0,1]←0; N2FOUND←N3FOUND←0;
04000 GETPICTURE;
04100 IF EXFLAG=10 THEN GO TO FAIL_COMP;
04200 IF DIS_EYE THEN DISPLAY;
04300 EJINIT; ⊃ This initializes edge operator;
04400
04500 TRY_AGAIN: X1←LOOK_AT[2]-(LOOK_AT[4] DIV 2);
04600 X2←LOOK_AT[2]+(LOOK_AT[4] DIV 2);
04700 Y1←LOOK_AT[3]-(LOOK_AT[5] DIV 2);
04800 Y2←LOOK_AT[3]+(LOOK_AT[5] DIV 2);
04900 DXY←(X2+Y2)/SQ2;
05000
05100 IF ¬DIS_EYE THEN EDG_TIM←CALL(0,"RUNTIM");
05200 FLINES: YFIN←EDGE_FIND(X1,Y1,X2,Y2); ⊃ Call on the edge operator;
05300 IF ¬DIS_EYE THEN
05400 BEGIN
05500 LIN_TIM←CALL(0,"RUNTIM");
05600 EDG_TIM←(LIN_TIM-EDG_TIM)/1000.;
05700 PRINT(EDG_TIM);
05800 END;
05900
06000 GET_LINES; ⊃ Call on the line finder;
06100 IF ¬DIS_EYE THEN
06200 BEGIN
06300 LIN_TIM←(CALL(0,"RUNTIM")-LIN_TIM)/1000.;
06400 PRINT(LIN_TIM);
06500 END;
06600 IF YFIN≠-1 THEN BEGIN Y1←YFIN; GO TO FLINES; ⊃ The edge
06700 array was too small so we have to go back; END;
06800 IF TOLER<1 THEN ROUGH_COMPARE;
06900 IF NLINES=0 THEN GO TO FAIL_COMP;
07000
07100
07200 ⊃ LOOKING FOR 1 LINE;
07300 IF MODLINES =1 THEN
07400 BEGIN
07500 IF DEB_EYE THEN OUTSTR("LOOKING FOR ONE LINE"ACRLF);
07600 IF NLINES=1 THEN BEGIN STORE_LINE(0); GO TO SUCCESS; END;
07700 IF ¬WANT_ALL THEN LASTLINE←1 ELSE
07800 BEGIN
07900 IF NLINES≤10 THEN LASTLINE←NLINES ELSE
08000 LASTLINE←10;
08100 END;
08200 MIN←2;
08300 FOR J←1 STEP 1 UNTIL LASTLINE DO
08400 BEGIN "ALL"
08500 MAX←0;
08600 FOR I←0 STEP 1 UNTIL NLINES-1 DO
08700 IF (TEMP←ABS(HUMPS[I,COSTHETA]*CORNMOD[1,COSTHETA]
08800 +HUMPS[I,SINTHETA]*CORNMOD[1,SINTHETA]))>MAX∧TEMP<MIN THEN
08900 BEGIN MAX←TEMP; ISAVE←I; END;
09000 MIN←MAX;
09100 STORE_LINE(ISAVE);
09200 END "ALL";
09300 GO TO SUCCESS;
09400 END;
09500
09600
09700 ⊃ LOOKING FOR A SIMPLE CORNER;
09800 IF MODLINES =2 THEN
09900 BEGIN "TWO"
10000 IF DEB_EYE THEN OUTSTR(" LOOKING FOR SIMPLE CORNER"ACRLF);
10100 IF NLINES<MODLINES THEN GO TO FOL2;
10200 EXTEND; ⊃ Call on vertex former;
10300 IF NVERTEX=0 THEN GO TO NEED2_VERT;
10400 TEST2_VERT: FOR I←1 STEP 1 UNTIL NVERTEX DO
10500 BEGIN "OUT"
10600 IF DEB_EYE THEN DIS_VERT(I);
10700 IF DIR_TEST(I)∧DEB_EYE THEN DIS_VERT(I);
10800 IF VERTEX[I,3]=MODLINES THEN TRY(I);
10900 NEXT2: END "OUT";
11000
11100 NEED2_VERT: ⊃ Here we form test vertices; N2FOUND←0;
11200 FOR N←0 STEP 1 UNTIL NLINES-2 DO
11300 FOR J←N+1 STEP 1 UNTIL NLINES-1 DO
11400 IF TWO_LINE_VERT(N,J,MODLINES)∧¬WANT_ALL THEN GO TO SUCCESS;
11500 IF EXT_LINE THEN GO TO FAIL_COMP;
11600 IF DEB_EYE∧N2FOUND>0 THEN
11700 OUTSTR(" HAVE FOUND "&CVS(N2FOUND)&" COMBINATIONS THAT WORK,
11800 BUT NO VERTICIES WITH THESE COMBINATIONS! "ACRLF);
11900
12000 FOL2: IF TOLER≥1 THEN
12100 BEGIN
12200 IF DIR_EYE[0,1]=0 THEN GO TO FAIL_COMP
12300 ELSE GO TO SUCCESS;
12400 END;
12500 FOR K←0 STEP 1 UNTIL NLINES-1 DO
12600 BEGIN "FOLW2"
12700 IF HUMPS[K,3]>0∨HUMPS[K,4]>0 THEN GO TO LAST3;
12800 IF ABSFIT(K,1)∧¬ABSFIT(K,2) THEN
12900 BEGIN ISAVE←1; OTHER←2; GO TO NEX2; END;
13000 IF ABSFIT(K,2)∧¬ABSFIT(K,1) THEN
13100 BEGIN ISAVE←2; OTHER←1; END ELSE GO TO LAST2;
13200 NEX2: SIGX←SIGN(CORNMOD[ISAVE,SINDIR]);
13300 SIGY←SIGN(CORNMOD[ISAVE,COSDIR]);
13400 FOLLOW[4]←SIGX*ABS(HUMPS[K,SINTHETA]);
13500 FOLLOW[5]←SIGY*ABS(HUMPS[K,COSTHETA]);
13600 FOLLOW[6]←HUMPS[K,CEE];
13700 IF ABS(HUMPS[K,SINTHETA])>0.5 THEN
13800 BEGIN
13900 IF SIGX=HUMPS[K,SIGNX] THEN I←HUMPS[K,6]
14000 ELSE I←FPOINT;
14100 END ELSE
14200 BEGIN
14300 IF SIGY=HUMPS[K,SIGNY] THEN I←HUMPS[K,6]
14400 ELSE I←FPOINT;
14500 END;
14600 XC←HUMPS[K,I+1]+2.*FOLLOW[4];
14700 YC←HUMPS[K,I+2]+2.*FOLLOW[5];
14800 IF ABS(XC-LOOK_AT[2])<DELTA_X
14900 ∧ABS(YC-LOOK_AT[3])<DELTA_Y THEN
15000 BEGIN
15100 IF DEB_EYE THEN OUTSTR(" HAVE FOUND THE END OF LINE "&CVS(K)
15200 &" BUT NO CORNER"ACRLF);
15300 DX←CORNMOD[OTHER,SINDIR];
15400 DY←CORNMOD[OTHER,COSDIR];
15500 NUM_LINES←NLINES;
15600 SET_FOR_SCAN(XC,YC,DX,DY); ⊃ Here we look
15700 for a particular line;
15800 IF NUM_LINES=NLINES THEN GO TO DNEXT;
15900 FOR L←NUM_LINES STEP 1 UNTIL NLINES-1 DO
16000 IF ABSFIT(L,OTHER)∧TWO_LINE_VERT(L,K,MODLINES)
16100 ∧¬WANT_ALL THEN GO TO SUCCESS;
16200 NLINES←NUM_LINES;
16300 DNEXT: IF DIS_EYE THEN SHOW_LINES;
16400 GO TO LAST2;
16500 END;
16600 IF NLINES>1 THEN GO TO LAST2;
16700 FOLLOW[2]←HUMPS[K,I+1];
16800 FOLLOW[3]←HUMPS[K,I+2];
16900 EXFLAG←6;
17000 GO TO FAILURE;
17100 LAST2: END "FOLW2";
17200 IF DIR_EYE[0,1]≠0 THEN GO TO SUCCESS;
17300 IF SEARCH≥1∨N2FOUND≠1 THEN GO TO FAIL_COMP;
17400 EXT_LINE←-1;
17500 GO TO NEED2_VERT;
17600 END "TWO";
17700
17800
17900
18000 ⊃ LOOKING FOR A PHYSICAL CORNER;
18100 IF MODLINES =3 THEN
18200 BEGIN
18300 IF DEB_EYE THEN OUTSTR(" LOOKING FOR PHYSICAL CORNER "ACRLF);
18400 IF NLINES=1 THEN GO TO FOL3;
18500 EXTEND; ⊃ Call on vertex former;
18600 IF NLINES=1 THEN GO TO FOL3;
18700 IF NLINES=2 THEN GO TO TWO_LINES;
18800 IF NVERTEX=0 THEN GO TO NEED3_VERT;
18900 TEST3_VERT: FOR I←1 STEP 1 UNTIL NVERTEX DO
19000 BEGIN
19100 IF DEB_EYE THEN DIS_VERT(I);
19200 IF DIR_TEST(I)∧DEB_EYE THEN DIS_VERT(I);
19300 IF VERTEX[I,3]=MODLINES THEN TRY(I);
19400 NEXT3: END;
19500 END;
19600 NEED3_VERT: N3FOUND←0;
19700 FOR N←0 STEP 1 UNTIL NLINES-3 DO
19800 FOR J←N+1 STEP 1 UNTIL NLINES-2 DO
19900 FOR L←J+1 STEP 1 UNTIL NLINES -1 DO
20000 IF THREE_LINE_VERT(L,J,N)∧¬WANT_ALL THEN GO TO SUCCESS;
20100 IF DEB_EYE∧N3FOUND>0 THEN
20200 OUTSTR(" HAVE FOUND "&CVS(N3FOUND)&" COMBINATIONS THAT WORK,
20300 BUT NO VERTICIES WITH THESE COMBINATIONS! "ACRLF);
20400
20500 IF TOLER≥1 THEN
20600 BEGIN
20700 IF DIR_EYE[0,1]=0 THEN GO TO FAIL_COMP
20800 ELSE GO TO SUCCESS;
20900 END;
21000 TWO_LINES: FOR N←0 STEP 1 UNTIL NLINES-2 DO
21100 BEGIN
21200 IF HUMPS[N,3]>0∨HUMPS[N,4]>0 THEN CONTINUE;
21300 FOR J←N+1 STEP 1 UNTIL NLINES-1 DO
21400 IF HUMPS[J,3]<0∧HUMPS[J,4]<0 THEN
21500 TWO_LINE_VERT(N,J,MODLINES);
21600 END;
21700 NVERT←NVERTEX;
21800 ABOVE: FOR J←1 STEP 1 UNTIL NVERT DO
21900 BEGIN "TWOL"
22000 LABEL ONWARD;
22100 IF DEB_EYE THEN
22200 OUTSTR(" LOOKING FOR A THIRD LINE IN TWO LINE VERTICIES"ACRLF);
22300
22400 IF VERTEX[J,3]≠2 THEN CONTINUE;
22500 X←VERTEX[J,1];
22600 Y←VERTEX[J,2];
22700 IF ABS(X-LOOK_AT[2])>LOOK_AT[4]/2.
22800 ∨ABS(Y-LOOK_AT[3])>LOOK_AT[5]/2. THEN GO TO FEW_LINES;
22900 IF ¬DEB_EYE THEN GO TO ONWARD;
23000 OUTSTR(" LOOKING AT VERTEX "&CVS(J)ACRLF);
23100 INCHWL;
23200 DIS_VERT(J);
23300 ONWARD: IF DIR_TEST(J) THEN CONTINUE;
23400 N←VERTEX[J,4];
23500 NI←VERTEX[J,5];
23600 IF (L1←BESTFIT(N))∧(L2←BESTFIT(NI))∧L1≠L2 THEN
23700 FOR K←1 STEP 1 UNTIL MODLINES DO
23800 IF K≠L1∧K≠L2 THEN
23900 BEGIN
24000 OTHER←K;
24100 GO TO NEXT4;
24200 END;
24300 GO TO LAST4;
24400 NEXT4: IF DEB_EYE THEN OUTSTR("HAVE FOUND TWO LINES MAKING A VERTEX
24500 BUT CANNOT FIND THE THIRD LINE"ACRLF);
24600 NUM_LINES←NLINES;
24700 DX←CORNMOD[OTHER,SINDIR];
24800 DY←CORNMOD[OTHER,COSDIR];
24900 SET_FOR_SCAN(X,Y,DX,DY); ⊃ Here we look
25000 for a particular line;
25100 IF NUM_LINES=NLINES THEN GO TO DNEXT1;
25200 FOR L←NUM_LINES STEP 1 UNTIL NLINES-1 DO
25300 IF ABSFIT(L,OTHER)∧THREE_LINE_VERT(L,N,NI)
25400 ∧¬WANT_ALL THEN GO TO SUCCESS;
25500 NLINES←NUM_LINES;
25600 DNEXT1: IF DIS_EYE THEN SHOW_LINES;
25700 GO TO LAST4;
25800 FEW_LINES: IF NLINES≥3 THEN GO TO LAST4;
25900 FOLLOW[2]←X;
26000 FOLLOW[3]←Y;
26100 EXFLAG←5;
26200 GO TO FAILURE;
26300 LAST4: END "TWOL";
26400 FOL3: IF TOLER≥1 THEN
26500 BEGIN
26600 IF DIR_EYE[0,1]=0 THEN GO TO FAIL_COMP
26700 ELSE GO TO SUCCESS;
26800 END;
26900 FOR K←0 STEP 1 UNTIL NLINES-1 DO
27000 BEGIN "FOLW3"
27100 IF HUMPS[K,3]>0∨HUMPS[K,4]>0 THEN GO TO LAST3;
27200 IF ABSFIT(K,1)∧¬ABSFIT(K,2)∧¬ABSFIT(K,3) THEN
27300 BEGIN ISAVE←1; GO TO NEX3; END;
27400 IF ABSFIT(K,2)∧¬ABSFIT(K,1)∧¬ABSFIT(K,3) THEN
27500 BEGIN ISAVE←2; GO TO NEX3; END;
27600 IF ABSFIT(K,3)∧¬ABSFIT(K,1)∧¬ABSFIT(K,2) THEN
27700 ISAVE←3 ELSE GO TO LAST3;
27800 NEX3: SIGX←SIGN(CORNMOD[ISAVE,SINDIR]);
27900 SIGY←SIGN(CORNMOD[ISAVE,COSDIR]);
28000 FOLLOW[4]←SIGX*ABS(HUMPS[K,SINTHETA]);
28100 FOLLOW[5]←SIGY*ABS(HUMPS[K,COSTHETA]);
28200 FOLLOW[6]←HUMPS[K,CEE];
28300 IF ABS(HUMPS[K,SINTHETA])>0.5 THEN
28400 BEGIN
28500 IF SIGX=HUMPS[K,SIGNX] THEN I←HUMPS[K,6]
28600 ELSE I←FPOINT;
28700 END ELSE
28800 BEGIN
28900 IF SIGY=HUMPS[K,SIGNY] THEN I←HUMPS[K,6]
29000 ELSE I←FPOINT;
29100 END;
29200 IF ISAVE=1 THEN BEGIN OTHER←2; OTHER2←3; END
29300 ELSE IF ISAVE=2 THEN BEGIN OTHER←1; OTHER2←3; END
29400 ELSE BEGIN OTHER←1; OTHER2←2; END;
29500 XC←HUMPS[K,I+1]+2.*FOLLOW[4];
29600 YC←HUMPS[K,I+2]+2.*FOLLOW[5];
29700 IF ABS(XC-LOOK_AT[2])<DELTA_X
29800 ∧ABS(YC-LOOK_AT[3])<DELTA_Y THEN
29900 BEGIN
30000 ⊃ OUTSTR(" HAVE FOUND THE END OF A LINE BUT NO CORNER"ACRLF);
30100 DX←CORNMOD[OTHER,SINDIR];
30200 DY←CORNMOD[OTHER,COSDIR];
30300 NUM_LINES←NLINES;
30400 SET_FOR_SCAN(XC,YC,DX,DY); ⊃ Here we look
30500 for one of the model lines;
30600 IF NUM_LINES=NLINES THEN GO TO NEX6;
30700 FOR L←NUM_LINES STEP 1 UNTIL NLINES-1 DO
30800 IF ABSFIT(L,OTHER) THEN GO TO NEX4;
30900 GO TO NEX6;
31000 NEX4: DX←CORNMOD[OTHER2,SINDIR];
31100 DY←CORNMOD[OTHER2,COSDIR];
31200 SET_FOR_SCAN(XC,YC,DX,DY); ⊃ Here we look
31300 for the other model line;
31400 IF NLINES<NUM_LINES+2 THEN GO TO NEX6;
31500 FOR L←NUM_LINES+1 STEP 1 UNTIL NLINES-1 DO
31600 IF ABSFIT(L,OTHER2) THEN GO TO NEX5;
31700 GO TO NEX6;
31800 NEX5: FOR L←NUM_LINES STEP 1 UNTIL NLINES-2 DO
31900 FOR J←L+1 STEP 1 UNTIL NLINES-1 DO
32000 IF THREE_LINE_VERT(J,K,L)∧¬WANT_ALL THEN
32100 GO TO SUCCESS;
32200 NEX6: NLINES←NUM_LINES;
32300 IF DIS_EYE THEN SHOW_LINES;
32400 GO TO LAST3;
32500 END;
32600 IF NLINES>1 THEN GO TO LAST3;
32700 FOLLOW[2]←HUMPS[K,I+1];
32800 FOLLOW[3]←HUMPS[K,I+2];
32900 EXFLAG←6;
33000 GO TO FAILURE;
33100 LAST3: END "FOLW3";
33200 IF DIR_EYE[0,1]≠0 THEN GO TO SUCCESS;
33300 IF EXT_LINE∨SEARCH≥1∨N3FOUND≠1 THEN GO TO FAIL_COMP;
33400 EXT_LINE←-1;
33500 GO TO NEED3_VERT;
33600
33700
33800
33900
34000 SUCCESS: OUTSTR("FINDIMAG SUCCEEDED: "ACRLF);
34100 EXFLAG←0;
34200 RETURN;
34300
34400
34500 FAIL_COMP: EXFLAG←10;
34600 FAILURE: DIR_EYE[0,1]←0;
34700 OUTSTR("FINDIMAG-FAILED:" &"NO MATCHES FOUND"ACRLF
34800 &"NUMBER OF LINES = "&CVS(NLINES)&
34900 ", VERTICES = "&CVS(NVERTEX)ACRLF);
35000 END "FINDIMAG";
00100 PROCEDURE SRCHIMAG(INTEGER MODLINES,DIREC,SEARCH;
00200 REAL TOLER; REAL ARRAY CORNMOD);
00300
00400
00500 ⊃ Here we direct the search space by moving the window if
00600 search is >0. Otherwise we just call on FINDIMAG;
00700
00800
00900
01000 BEGIN "SRCHIMAG"
01100
01200
01300 SHORT INTEGER N,K,LSB,RSB,FLB,LLB,HWIDTH,HHIGHT,NCEN;
01400 SHORT INTEGER XIC0,YIC0,HDIM,J,L,LINE1,MODL,NCT2,ZOR4;
01500 SHORT REAL F, LENG, LO2,SINTH,COSTH,XP,YP;
01600 STRING CALSTR;
01700 LABEL PRINTR,OUT_DISP,AFT1;
01800
01900 DEFINE XMIN ="LOOK_AT[2] - (LOOK_AT[4] DIV 2) -LSIDE",
02000 YMIN = "LOOK_AT[3] - (LOOK_AT[5] DIV 2) - FLINE",
02100 XMAX = "LOOK_AT[2] + (LOOK_AT[4] DIV 2) - RSIDE",
02200 YMAX = "LOOK_AT[3] + (LOOK_AT[5] DIV 2) - LLINE";
02300 ⊃ These limits keep us from going off the disk picture;
02400
02500
02600 DEFINE ADVANCE="LOOK_AT[2]←XIC0+J*HWIDTH; LOOK_AT[3]←YIC0+L*HHIGHT;
02700 IF XMIN<0 THEN LOOK_AT[2] ← LSIDE +(LOOK_AT[4] DIV 2);
02800 IF YMIN<0 THEN LOOK_AT[3] ← FLINE +(LOOK_AT[5] DIV 2);
02900 IF YMAX>0 THEN LOOK_AT[3] ← LLINE -(LOOK_AT[5] DIV 2);
03000 IF XMAX>0 THEN LOOK_AT[3] ← RSIDE -(LOOK_AT[4] DIV 2);
03100
03200 EXFLAG←0; FINDIMAG(MODLINES,DIREC,1,TOLER,CORNMOD);
03300 IF EXFLAG=0 THEN GO TO PRINTR; ⊃ Success;
03400 IF EXFLAG=1 THEN RETURN; ⊃ Poor window;
03500 IF EXFLAG=5 THEN CHECK_VERT; ⊃ A VERTEX LOCATION
03600 TO EXAMINE HAS BEEN FOUND;
03700 IF EXFLAG=6 THEN FOL_ONE; ⊃ A LINE TO FOLLOW
03800 HAS BEEN FOUND; ";
03900
04000 PROCEDURE CHECK_VERT;
04100
04200 ⊃ Here we move the window to check a promising vertex location;
04300
04400 BEGIN "CHECK"
04500 SHORT REAL X,Y;
04600 INTEGER J;
04700 LABEL FORGET_IT, FIRST;
04800 FIRST: X←FOLLOW[2];
04900 Y←FOLLOW[3];
05000 FOR J←1 STEP 1 UNTIL INTS DO
05100 IF ABS(X-INTER[1,J])<DINT∧ABS(Y-INTER[2,J])<DINT THEN
05200 BEGIN
05300 OUTSTR(" HAVE SEEN THIS VERTEX BEFORE"ACRLF);
05400 GO TO FORGET_IT;
05500 END;
05600 IF ABS(X-LOOK_AT[2])>SEARCH*LOOK_AT[4]
05700 ∨ABS(Y-LOOK_AT[3])>SEARCH*LOOK_AT[5] THEN
05800 FORGET_IT: BEGIN EXFLAG←10; RETURN; END;
05900 OUTSTR(" MOVING WINDOW TO LOOK FOR A VERTEX AT
06000 -- X="&CVG(X)&" Y="&CVG(Y)ACRLF);
06100 INTS←INTS+1;
06200 LOOK_AT[2]←INTER[1,INTS]←X;
06300 LOOK_AT[3]←INTER[2,INTS]←Y;
06400 FINDIMAG(MODLINES,DIREC,1,TOLER,CORNMOD);
06500 IF EXFLAG=0 THEN GO TO PRINTR;
06600 IF EXFLAG=6 THEN GO TO FIRST;
06700 END "CHECK";
06800
06900 PROCEDURE FOL_ONE;
07000 BEGIN "FOL"
07100 SHORT INTEGER D,JJ;
07200 SHORT REAL DX_LINE, DY_LINE,C_LINE,X_END,Y_END;
07300 BOOLEAN TEST;
07400 LABEL FIRST,SECOND;
07500
07600 ⊃ Following one line to find simple corner;
07700
07800 TEST←0;
07900 FIRST: X_END←FOLLOW[2];
08000 Y_END←FOLLOW[3];
08100 DX_LINE←LIN[1,LINS+1]←FOLLOW[4];
08200 DY_LINE←LIN[2,LINS+1]←FOLLOW[5];
08300 C_LINE←LIN[3,LINS+1]←FOLLOW[6];
08400 OUTSTR(" FOLLOWING A LINE "ACRLF);
08500 IF DEB_EYE THEN OUTSTR(" DX OF LINE-FOUND = "&CVG(DX_LINE)&"
08600 DY OF LINE-FOUND = "&CVG(DY_LINE)ACRLF);
08700 IF TEST THEN BEGIN LINS←LINS-1; GO TO SECOND; END;
08800 FOR JJ←1 STEP 1 UNTIL LINS DO
08900 IF ABS(DX_LINE-LIN[1,JJ])<NDTH/2.
09000 ∧ABS(DY_LINE-LIN[2,JJ])<NDTH/2.
09100 ∧ABS(C_LINE-LIN[3,JJ])<NDC/2. THEN
09200 BEGIN
09300 EXFLAG←10;
09400 OUTSTR(" HAVE FOLLOWED THIS LINE BEFORE"ACRLF);
09500 RETURN;
09600 END;
09700 SECOND: IF ABS(X_END-LOOK_AT[2])>SEARCH*LOOK_AT[4]
09800 ∨ABS(Y_END-LOOK_AT[3])>SEARCH*LOOK_AT[5] THEN
09900 BEGIN EXFLAG←10; RETURN; END;
10000 LOOK_AT[2]← X_END+(LOOK_AT[4]/2.-8)*DX_LINE;
10100 LOOK_AT[3]← Y_END+(LOOK_AT[5]/2.-8)*DY_LINE;
10200 LINS←LINS+1;
10300 FINDIMAG(MODLINES,DIREC,1,TOLER,CORNMOD);
10400 IF EXFLAG=0 THEN GO TO PRINTR; ⊃ Have found corner;
10500 IF EXFLAG=6 THEN BEGIN TEST←-1;GO TO FIRST; END;
10600 ⊃ Still following this line;
10700 IF EXFLAG=10 THEN RETURN; ⊃ Failure;
10800 IF EXFLAG=5 THEN CHECK_VERT; ⊃ Found a possible vertex
10900 location to check;
11000 IF EXFLAG=0 THEN GO TO PRINTR; ⊃ Have found corner;
11100 END "FOL";
11200
11300
11400 INTS←LINS←0;
11500 IF TOLER≤0 THEN TOLER←1.;
11600 IF SEARCH≤0 THEN
11700 BEGIN
11800 FINDIMAG(MODLINES,DIREC,SEARCH,TOLER,CORNMOD);
11900 IF EXFLAG=0 THEN GO TO PRINTR;
12000 RETURN;
12100 END;
12200
12300 HWIDTH←LOOK_AT[4]-6; HHIGHT←LOOK_AT[5]-6; ⊃ We overlap window
12400 by 6 units;
12500 XIC0←LOOK_AT[2]; YIC0←LOOK_AT[3];
12600 IF (HDIM←HWIDTH)>HHIGHT THEN HDIM←HHIGHT;
12700 LSB←XIC0-SEARCH*HWIDTH; RSB←XIC0+SEARCH*HWIDTH;
12800 FLB←YIC0-SEARCH*HWIDTH; LLB←YIC0+SEARCH*HWIDTH;
12900 J←L←0; ADVANCE;
13000
13100 ⊃ Search;
13200
13300 FOR K←1 STEP 1 UNTIL SEARCH DO BEGIN
13400 L←-K; FOR J←-K STEP 1 UNTIL K DO BEGIN ADVANCE END;
13500 J←K; FOR L←-K+1 STEP 1 UNTIL K DO BEGIN ADVANCE END;
13600 L←K; FOR J←K-1 STEP -1 UNTIL -K DO BEGIN ADVANCE END;
13700 J←-K; FOR L←K-1 STEP -1 UNTIL -K+1 DO BEGIN ADVANCE END;
13800 END;
13900 OUTSTR("SRCHIMAG-FAILED: NOTHING FOUND IN SEARCH SPACE"ACRLF); RETURN;
14000
14100
14200
14300
14400 PRINTR: IF DIS_EYE THEN
14500 BEGIN "DIS"
14600 LENG←SMALLER(15.,SQRT(LOOK_AT[4]*LOOK_AT[5])/2.);
14700 LO2←LENG/2;
14800 DPYSET(BUF);
14900 IF CAL_COMP THEN DPYBIG(6);
15000 BOUNDARY(X1,Y2,X2,Y1);
15100 FOR N←1 STEP 1 UNTIL NCORNERS DO
15200 BEGIN
15300 NCEN←NCT2←2*(N-1);
15400 IF MODLINES=1 THEN NCT2←N-1;
15500 IF ¬DEB_EYE THEN GO TO AFT1;
15600 IF MODLINES=1 THEN
15700 OUTSTR("X-CENTER AT "&CVG(DIR_EYE[N-1,2])&
15800 ", Y-CEMTER AT "&CVG(DIR_EYE[N-1,3])ACRLF)
15900 ELSE OUTSTR("X-VERTEX AT "&CVG(DIR_EYE[NCT2,2])&
16000 ", Y-VERTEX AT "&CVG(DIR_EYE[NCT2,3])ACRLF);
16100 AFT1: AIVECT(-500,250);
16200 IF DIR_EYE[0,1]=-1 THEN
16300 DPYSST(" POSSIBLE CORNER")
16400 ELSE IF MODLINES>1 THEN
16500 BEGIN
16600 IF NCORNERS=1 THEN
16700 CALSTR←CVS(NCORNERS)&" CORNER FOUND"
16800 ELSE CALSTR←CVS(NCORNERS)&" CORNERS FOUND";
16900 DPYSST(" "&CALSTR);
17000 END ELSE
17100 BEGIN
17200 IF NCORNERS=1 THEN
17300 CALSTR←CVS(NCORNERS)&" LINE FOUND"
17400 ELSE CALSTR←CVS(NCORNERS)&" LINES FOUND";
17500 DPYSST(" "&CALSTR);
17600 END;
17700
17800 FOR K←1 STEP 1 UNTIL MODLINES DO
17900 BEGIN
18000 IF K=2 THEN
18100 BEGIN
18200 ZOR4←0;
18300 NCT2←NCT2+1;
18400 END
18500 ELSE ZOR4←4;
18600 IF DEB_EYE THEN
18700 BEGIN
18800 OUTSTR("TH-VALUE(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+1])ACRLF);
18900 OUTSTR("C-VALUE(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+2])ACRLF);
19000 OUTSTR( " SIN(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+3])ACRLF);
19100 OUTSTR( " COS(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+4])ACRLF);
19200 END;
19300 IF MODLINES=1 THEN
19400 BEGIN
19500 SINTH←SIN(DIR_EYE[N-1,5]);
19600 COSTH←COS(DIR_EYE[N-1,5]);
19700 ARROW(DIR_EYE[N-1,2],DIR_EYE[N-1,3],COSTH,SINTH);
19800 AIVECT(TX(DIR_EYE[N-1,2]-LO2*DIR_EYE[N-1,7]),
19900 TY(DIR_EYE[N-1,3]-LO2*DIR_EYE[N-1,8]));
20000 AVECT(TX(DIR_EYE[N-1,2]+LO2*DIR_EYE[N-1,7]),
20100 TY(DIR_EYE[N-1,3]+LO2*DIR_EYE[N-1,8]));
20200 GO TO OUT_DISP;
20300 END;
20400 COSTH←COS(DIR_EYE[NCT2,ZOR4+1]);
20500 SINTH←SIN(DIR_EYE[NCT2,ZOR4+1]);
20600 XP←DIR_EYE[NCEN,2]-LO2*DIR_EYE[NCT2,ZOR4+3];
20700 YP←DIR_EYE[NCEN,3]-LO2*DIR_EYE[NCT2,ZOR4+4];
20800 ARROW(XP,YP,COSTH,SINTH);
20900 AIVECT(TX(DIR_EYE[NCEN,2]),TY(DIR_EYE[NCEN,3]));
21000 AVECT(TX(DIR_EYE[NCEN,2]-LENG*DIR_EYE[NCT2,ZOR4+3]),
21100 TY(DIR_EYE[NCEN,3]-LENG*DIR_EYE[NCT2,ZOR4+4]));
21200 END;
21300 OUT_DISP: END;
21400 DPYOUT(1);
21500 IF CAL_COMP THEN
21600 BEGIN
21700 CALSTR←"CORN"&CVS(CORNERNUMBER);
21800 CALCOMP(CALSTR,BUF);
21900 CORNERNUMBER←CORNERNUMBER+1;
22000 END;
22100 END "DIS";
22200 RETURN;
22300
22400
22500 OUTSTR("SRCHIMAG-FAILED: "ACRLF);
22600 END "SRCHIMAG";
22700